/*
 * SchedulerConnectionFactory.java is part of htn-example.
 *
 * SchedulerConnectionFactory.java is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * SchedulerConnectionFactory.java is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with SchedulerConnectionFactory.java.  If not, see <http://www.gnu.org/licenses/>.
 */
package org.htn.telescopes.rtml;

import java.io.File;
import java.io.FileInputStream;
import java.security.KeyStore;

import javax.net.ssl.KeyManager;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;

import ngat.net.ConnectionFactory;
import ngat.net.IConnection;
import ngat.net.SocketConnection;
import ngat.net.UnknownResourceException;

public class SchedulerConnectionFactory implements ConnectionFactory
{
	/** Singleton object */
	public static SchedulerConnectionFactory connectionFactory;

	/** Returns a reference to the TEAConnectionFactory.
	 * Valid conection IDs are:-
	 *
	 * <dl>
	 *  <dt>OSS<dd>OSS Transaction Server: For ongoing DB entries and corrections.
	 *  <dt>CTRL<dd>RCS Control Server: For status comands.
	 *  <dt>TOCS<dd>RCS TOC Server: For TO control.
	 * </dl>
	 */
	public static SchedulerConnectionFactory getConnectionFactory() 
	{
		if (connectionFactory == null)
			connectionFactory = new SchedulerConnectionFactory();
		return connectionFactory; 
	}
	
	private SchedulerConnectionFactory()
	{
	}
    
	
    public IConnection createConnection(String connId) throws UnknownResourceException 
    {
    
		if (connId.equals("CTRL")) 
		{
			return new SocketConnection(ConfigurationManager.getManager().getCtrlHost(), 
					ConfigurationManager.getManager().getCtrlPort());
		} 
		else if (connId.equals("OSS")) 
		{
			return new SocketConnection(ConfigurationManager.getManager().getOssHost(),
					ConfigurationManager.getManager().getOssPort());
		} 
/*
// TODO: no secure access for now
	else if (connId.equals("OSS_SECURE")) 
		{

		    try {
			KeyManager[]   kms = getKeyManagers(ossKeyFile, ossPassword);
			TrustManager[] tms = getTrustManagers(ossTrustFile);
			
			SSLContext context = SSLContext.getInstance("TLS");
			
			context.init(kms, tms, null);
			
			SSLSocketFactory secureSocketFactory = (SSLSocketFactory)context.getSocketFactory();
			
			return new SocketConnection(ossHost, ossPort, secureSocketFactory );
			
		    } catch (Exception e) {
			e.printStackTrace();
			throw new UnknownResourceException("Unable to create secure connection: "+e);
		    }
		} 
*/
		else
		    throw new UnknownResourceException("Not known: "+connId);
	}

    private KeyManager[] getKeyManagers(File keyStore, String password) throws Exception {
        String alg = KeyManagerFactory.getDefaultAlgorithm();
        KeyManagerFactory kmf = KeyManagerFactory.getInstance(alg);
        FileInputStream fis = new FileInputStream(keyStore);
        KeyStore ks = KeyStore.getInstance("jks");
        ks.load(fis, password.toCharArray());
        fis.close();
        kmf.init(ks, password.toCharArray());
        KeyManager[] kms = kmf.getKeyManagers();
        return kms;
    }

    private TrustManager[] getTrustManagers(File trustStore) throws Exception {

        String alg = TrustManagerFactory.getDefaultAlgorithm();
        TrustManagerFactory tmf = TrustManagerFactory.getInstance(alg);
        FileInputStream fis = new FileInputStream(trustStore);
        KeyStore ks = KeyStore.getInstance("jks");
        ks.load(fis, "public".toCharArray());
        fis.close();
        tmf.init(ks);
        TrustManager[] tms = tmf.getTrustManagers();
        return tms;
    }
}
